package com.mojo.collection.map;

import java.lang.reflect.MalformedParameterizedTypeException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**
 * HashMap线程不安全示例
 *
 * @author <a href="mailto:mojo_jj@163.com">Mojo</a>
 */
public class HashMapDemo2 {
    static Map<Object, Object> map = new HashMap<>(2, 0.75f);

    public static void main(String[] args) {
        // 线程不安全-循环链表示例
        // infiniteLoop();
        threadUnsafe();
    }

    private static void threadUnsafe() {
        Map<Object, Object> hashMap = new ConcurrentHashMap<>();

        Thread thread = new Thread("thread 1") {

            @Override
            public void run() {
                for (int i = 0; i < 1000; i++) {
                    try {
                        TimeUnit.MICROSECONDS.sleep(new Random(100).nextInt());
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }

                    hashMap.put(i, UUID.randomUUID().toString().substring(0, 8));

                }
            }
        };
        Thread thread2 = new Thread("thread 2") {

            @Override
            public void run() {
                for (int i = 0; i < 2000; i++) {
                    try {
                        TimeUnit.MICROSECONDS.sleep(new Random(100).nextInt());
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }

                    hashMap.put(i, UUID.randomUUID().toString().substring(0, 8));

                }
            }
        };
        thread.start();
        thread2.start();
        try {
            thread.join();
            thread2.join();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        // 线程的size随机在变
        System.out.println(hashMap.size());
    }

    private static void infiniteLoop() {
        map.put(1, "a");
        new Thread("thread 1") {
            @Override
            public void run() {
                map.put(3, "b");
                System.out.println("Thread 1 :" + map);

            }
        }.start();
        new Thread("thread 2") {
            @Override
            public void run() {
                map.put(7, "c");
                System.out.println("Thread 1 :" + map);
            }
        }.start();
        System.out.println(map);
    }
}
